class Person(object):  # 单例类
    __instance = None  # 加上__  表示是私有的 只在这个类中使用 这样可以保护单例类
    __is_first = True

    def __new__(cls, *args, **kwargs):  # new方法创建返回一个对象
        print('__new__')
        # 单例模式的设计：当第一次变量没有引用对象的时候 创建一个对象给变量 然后返回 然后当判断有值了 就把之前的对象再次返回
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, name):  # init魔法方法设置对象的属性
        if Person.__is_first:
            print('__init__')
            self.name = name
            Person.__is_first = not Person.__is_first

    # def __str__(self):  # str魔法方法 监听属性信息的变化
    #     return '名字： %s' %  self.name
    #
    # def __del__(self):  # del监听对象是否被销毁
    #     print('再见')


xiaoming = Person('xiaoming')
print(xiaoming.name)  # 如果把str和del都注释掉 那么这个打印就是一串内存地址
xiaoli = Person('xiaoli')
print(xiaoli.name)

# 分析：执行Person（）调用new方法 判断instance没有引用对象 则创建一个对象给instance 然后返回该对象并执行init方法 把对象赋给xiaoming 打印内存地址
# 然后第二次Person（）继续调用new方法 发现instance已经引用了之前那个对象 跳出判断 继续返回该对象并执行init方法 并把该对象赋给xiaoli 打印相同的内存地址

#  单例模式：有着相同内存地址的对象用不同的变量进行引用 对象的属性信息也是一致的
